/**
 * Copyright (C) 2013-2014 the original author or authors.
 */
package com.foreveross.bsl.cmd;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.foreveross.bsl.Command;
import com.foreveross.bsl.Config;
import com.foreveross.bsl.MessageStatistics;
import com.foreveross.bsl.openfire.OpenfireClient;
import com.foreveross.bsl.openfire.ReceiveStatisticMessageListener;

/**
 * xxx
 *
 * @author Wangyi
 * @version v1.0
 *
 * @date 2013-12-6
 *
 */
public class OpenfireMsgReceiveCmd implements Command {
	
	private static final Logger log = LoggerFactory.getLogger(OpenfireMsgReceiveCmd.class);
	private static final int COUNT_DIV_STEP=10;
	
	private MessageStatistics msgStat;
	private ReceiveStatisticMessageListener receiveStatisticMessageListener;
	private ExecutorService executorService;
	private final Config config;
	
	public OpenfireMsgReceiveCmd(MessageStatistics msgStat, Config config){
		this.msgStat=msgStat;
		this.receiveStatisticMessageListener=new ReceiveStatisticMessageListener(msgStat);
		this.config=config;
		
		this.executorService=Executors.newFixedThreadPool(20);
	}
	
	@Override
	public void execute() {
		int m=this.getClientCount(), from=this.getFrom();
		int n=0, ndiv=m/COUNT_DIV_STEP, nmod=m%COUNT_DIV_STEP;
		log.info("开始创建客户端,要求客户端数：{}", m);
		for(n=0; n<ndiv; n++){
			executorService.execute(new ReceiveClientCreateTask(n*COUNT_DIV_STEP+from, COUNT_DIV_STEP));
		}
		if(nmod>0){
			executorService.execute(new ReceiveClientCreateTask(n*COUNT_DIV_STEP+from, nmod));
		}
	}
	
	public MessageStatistics getMessageStatistics(){
		return this.msgStat;
	}
	
	private AtomicInteger n=new AtomicInteger();
	private AtomicInteger nError=new AtomicInteger();
	
	class ReceiveClientCreateTask implements Runnable{
		
		private int from;
		private int count;
		
		ReceiveClientCreateTask(int from, int count){
			this.from=from;
			this.count=count;
		}
		
		@Override
		public void run() {
			int to=from+count-1;
			log.debug("create rang: {}->{}", from, to);
			for(int i=from; i<=to; i++){
				try {
					doCreateClient(OpenfireClient.PREFIX_USERNAME+i, OpenfireClient.PREFIX_PWD+i);
				} catch (Exception e) {
					nError.incrementAndGet();
					log.error("创建第"+i+"客户端出错", e);
				}
			}
			n.addAndGet(this.count);
			log.info("已完成{}/{}, 错误:{}", n.get(), getClientCount(), nError.get());
		}
	}
	
	protected void doCreateClient(String username, String password) throws Exception {
		OpenfireClient client=new OpenfireClient(this.getHost(), this.getPort());
		client.setReceiveStatisticMessageListener(receiveStatisticMessageListener);
		client.setUsername(username);
		client.setPassword(password);
		client.login();
	}

	/**
	 * @return the host
	 */
	public String getHost() {
		return this.config.getProperty("openfire.host", true);
	}

	/**
	 * @return the port
	 */
	public int getPort() {
		return Integer.parseInt(this.config.getProperty("openfire.port", "5222"));
	}

	/**
	 * @return the clientCount
	 */
	public int getClientCount() {
		return Integer.parseInt(this.config.getProperty("openfire.receiver.count", "1"));
	}

	/**
	 * @return the from
	 */
	public int getFrom() {
		return Integer.parseInt(this.config.getProperty("openfire.receiver.from", "1"));
	}

	/**
	 * @return the receiveStatisticMessageListener
	 */
	public ReceiveStatisticMessageListener getReceiveStatisticMessageListener() {
		return receiveStatisticMessageListener;
	}

	/**
	 * @return the msgStat
	 */
	public MessageStatistics getMsgStat() {
		return msgStat;
	}

	/**
	 * @return the config
	 */
	public Config getConfig() {
		return config;
	}
}
